#include "serialportutils.h"

#include <QSerialPortInfo>

//构造函数
SerialPortUtils::SerialPortUtils(QObject *parent)
    : QObject(parent), serialPort(new QSerialPort(this))
{
    connect(serialPort, &QSerialPort::readyRead, this, &SerialPortUtils::onDataReceived);
}
//析构函数
SerialPortUtils::~SerialPortUtils()
{
    if (serialPort->isOpen()) {
        serialPort->close();
    }
    delete serialPort;
    serialPort  = nullptr;
    delete monitorThread;
}
//获取串口列表
QStringList SerialPortUtils::getAvailablePorts()
{
    QStringList portList;
    foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) {
        portList.append(info.portName());
    }
    return portList;
}
//连接串口
void SerialPortUtils::connectToPort(const QString &portName, int baudRate , const bool isAuto )
{
    QStringList ports = getAvailablePorts();
    if (ports.isEmpty()) {
        qDebug() << "没有可用串口列表:" << ports;
        emit connectionStatusChanged(ConnectionStatus::ConnectionFailed,"未检测到可用串口");
        return;
    }
    if( isAuto ){
        for (const QString &str : ports) {
            qDebug() << "connectToPort" <<  str;
            auto res = _connectPort(str, baudRate);
            if (res.first) {
                //连接成功
                return;
            }
        }
        emit connectionStatusChanged(ConnectionStatus::ConnectionFailed,"打开串口失败");
        return;
    }
    auto res = _connectPort(portName, baudRate);
    if (!res.first) {
        // 显示连接失败状态
        emit connectionStatusChanged(ConnectionStatus::ConnectionFailed,res.second);
    }
}


//连接到串口
QPair<bool, QString> SerialPortUtils::_connectPort(const QString &portName, int baudRate)
{
    // 显示连接状态
    // 如果没有接收者，可能是连接的对象已被销毁
    if (receivers(SIGNAL(connectionStatusChanged(ConnectionStatus))) == 0) {
        qDebug() << "警告：没有信号接收者";
    }
    emit connectionStatusChanged(ConnectionStatus::Connecting);
    // 配置串口
    serialPort->setPortName(portName);
    serialPort->setBaudRate(baudRate);
    serialPort->setDataBits(QSerialPort::Data8); // 8数据位
    serialPort->setParity(QSerialPort::NoParity); // 无奇偶校验
    serialPort->setStopBits(QSerialPort::OneStop); // 1停止位
    serialPort->setFlowControl(QSerialPort::NoFlowControl); // 无流控制
    // 打开串口
    if (serialPort->open(QIODevice::ReadWrite)) {
        // 显示连接成功状态
        emit connectionStatusChanged(ConnectionStatus::Connected);
        //开启守护线程
        monitorThread = new SerialPortMonitorThread(serialPort, this);
        connect(monitorThread, &SerialPortMonitorThread::connectionLost, this, [this]() {
            emit connectionStatusChanged(ConnectionStatus::Disconnected);
            //断开连接
            qDebug() << "串口连接丢失，断开连接";
        });
        monitorThread->start();
        return qMakePair(true,"连接成功");
    } else {
        return qMakePair(false, serialPort->errorString());
    }
}
//断开连接
void SerialPortUtils::disconnectPort()
{
    if (serialPort->isOpen()) {
        serialPort->close();
        emit connectionStatusChanged(ConnectionStatus::Disconnected);
    }
    if(monitorThread){
        monitorThread->quit();
        monitorThread->wait();
    }
}
//发送数据
void SerialPortUtils::sendData(const QByteArray &data)
{
    if (serialPort->isOpen()) {
        serialPort->write(data);
    } else {
        emit connectionStatusChanged(ConnectionStatus::ConnectionFailed,"串口未打开，发送失败");
    }
}
//接受到的数据
void SerialPortUtils::onDataReceived()
{
    QByteArray data = serialPort->readAll();
    emit dataReceived(data);  // 通过信号将数据传递出去
}

//是否连接
bool SerialPortUtils::isConnected() const
{
    return serialPort->isOpen();
}


